package site.zsxeee.work.spring.oa.shiro

import org.apache.shiro.authc.*
import org.apache.shiro.authc.credential.HashedCredentialsMatcher
import org.apache.shiro.authz.AuthorizationInfo
import org.apache.shiro.authz.SimpleAuthorizationInfo
import org.apache.shiro.crypto.hash.Sha256Hash
import org.apache.shiro.realm.AuthorizingRealm
import org.apache.shiro.subject.PrincipalCollection
import org.apache.shiro.util.ByteSource
import org.springframework.beans.factory.annotation.Autowired
import site.zsxeee.work.spring.oa.database.entity.User
import site.zsxeee.work.spring.oa.database.repository.UserRepository

class UserRealm : AuthorizingRealm() {
    @Autowired
    private lateinit var userRepository: UserRepository

    init {
        this.credentialsMatcher = HashedCredentialsMatcher().also {
            it.hashAlgorithmName = Sha256Hash.ALGORITHM_NAME
            it.isStoredCredentialsHexEncoded = true
            it.hashIterations = 1024
        }
    }

    override fun doGetAuthenticationInfo(token: AuthenticationToken): AuthenticationInfo {
        val userName = (token as UsernamePasswordToken).username ?: throw AccountException("Null userNames are not allowed by this realm.")


        val user = userRepository.findByUserName(userName)
                ?: throw UnknownAccountException("No account found for [$userName]")


//        //查询用户的角色和权限存到SimpleAuthenticationInfo中，这样在其它地方
//        //SecurityUtils.getSubject().getPrincipal()就能拿出用户的所有信息，包括角色和权限
//        val roles = roleService.getRolesByUserId(userDB.getUid())
//        val perms = permService.getPermsByUserId(userDB.getUid())
//        userDB.getRoles().addAll(roles)
//        userDB.getPerms().addAll(perms)

        return SimpleAuthenticationInfo(user, user.password, ByteSource.Util.bytes(user.salt), name)
    }

    override fun doGetAuthorizationInfo(principals: PrincipalCollection): AuthorizationInfo {
        val user = getAvailablePrincipal(principals) as User

        val info = SimpleAuthorizationInfo()
//        info.roles = user.roles
//        info.stringPermissions = user.perms
        return info
    }
}